package com.wf.mock.app.mina.app.processor.impl;

import java.util.List;
import java.util.concurrent.TimeUnit;

import lombok.extern.log4j.Log4j;

import org.apache.mina.core.session.IoSession;

import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import com.wf.mock.app.mina.app.processor.IMessageProcessor;
import com.wf.mock.app.mina.dto.RawMessageDTO;
import com.wf.mock.app.mina.dto.SplitMsgPacketDTO;

@Log4j
public class SplitMsgProcessorImpl implements IMessageProcessor {

	private static Cache<String, List<SplitMsgPacketDTO>> splitMsgPacketCache = CacheBuilder.newBuilder()
			.expireAfterWrite(10, TimeUnit.MINUTES).build();

	@Override
	public void process(RawMessageDTO msgDto, IoSession session) {

		RawMessageDTO combineRawMessage = combineRawMessage(msgDto);

		log.info("org msg : " + msgDto + "\r\n" + combineRawMessage);
		MainMessageProcessorImpl.getInstance().process(combineRawMessage, session);
	}

	private RawMessageDTO combineRawMessage(RawMessageDTO rawMessageDTO) {

		SplitMsgPacketDTO packedDto = JSONObject.toJavaObject(rawMessageDTO.getMsgBody(), SplitMsgPacketDTO.class);

		String cacheKey = packedDto.getUuid();
		List<SplitMsgPacketDTO> cachedPackedDtoList = splitMsgPacketCache.getIfPresent(cacheKey);

		RawMessageDTO ret = RawMessageDTO.EMPTYRAWMESSAGE;
		if (cachedPackedDtoList == null) {
			cachedPackedDtoList = Lists.newArrayList();
			cachedPackedDtoList.add(packedDto);
			splitMsgPacketCache.put(cacheKey, cachedPackedDtoList);
		} else {
			if (!cachedPackedDtoList.contains(packedDto)) {
				cachedPackedDtoList.add(packedDto);

				if (cachedPackedDtoList.size() >= packedDto.getSize()) {
					ret = SplitMsgPacketDTO.merger(cachedPackedDtoList);
					if (ret != RawMessageDTO.EMPTYRAWMESSAGE) {
						splitMsgPacketCache.invalidate(cacheKey);
					}
				}
			}

		}

		return ret;
	}

}
